home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/perl
- # -*- perl -*-
-
- # Foomatic printer XML file generator to get XML files corresponding
- # to manufacturer-supplied PostScript PPDs (or also PPDs from driver
- # packages).
-
- use Foomatic::Defaults;
- use Foomatic::DB;
- use Getopt::Std;
- use Data::Dumper;
- #use strict;
-
- my $debug = 0;
-
- # Program name
- $0 =~ m!/([^/]+)\s*$!;
- my $progname = ($1 || $0);
-
- help() if !@ARGV;
- #my ($opt_h, $opt_d, $opt_p, $opt_A, $opt_P, $opt_w);
- getopts("d:r:p:lb:f:nh");
- help() if $opt_h;
- my $drivers = $opt_d;
- my $rdriver = $opt_r;
- my $pdls = $opt_p;
- my $ppdlink = $opt_l;
- my $basedir = $opt_b;
- my $destdir = $opt_f;
- my $nomod = $opt_n;
-
- $ppdfile = $ARGV[0];
-
- if ($ppdlink && !$drivers) {
- $ppdlink = 0;
- warn("WARNING: \"-l\" set without supplying a driver via \"-d\". No PPD file links will get created!\n");
- }
-
- my $ppddlpath;
- if ($basedir) {
- $basedir =~ s:/+$::;
- if (! -d $basedir) {
- die ("PPD base directory $basedir does not exist!\n");
- }
- if (! -r $ppdfile) {
- $ppddlpath = $ppdfile;
- $ppdfile = $basedir . "/" . $ppdfile;
- if (! -r $ppdfile) {
- die ("Given PPD file not found, neither as $ppddlpath nor as $ppdfile!\n");
- }
- } else {
- $ppdfile =~ m:$basedir/(.*)$:;
- $ppddlpath = $1;
- }
- } else {
- if (! -r $ppdfile) {
- die ("Given PPD file $ppdfile not found!\n");
- }
- $ppddlpath = $ppdfile;
- }
-
- my $parameters = {
- ($drivers ? ('drivers' => [split(',', $drivers)]) : ()),
- ($rdriver ? ('recommendeddriver' => $rdriver) : ()),
- ($pdls ? ('pdls' => [split(',', $pdls)]) : ()),
- ($ppdlink ? ('ppdlink' => 1) : ()),
- ($basedir ? ('basedir' => $basedir) : ()),
- };
-
- my $db = Foomatic::DB->new();
- my $dat = ppdtoperl($ppdfile, $parameters);
- my @existing = $db->find_printer("$dat->{'make'}|$dat->{'model'}", 4, 1);
- foreach my $product (@{$dat->{ppdproduct}}) {
- my @pids = $db->find_printer("$dat->{'make'}|$product", 4, 1);
- push(@existing,
- grep {
- !Foomatic::DB::member($_, @existing);
- } @pids);
- }
- push(@existing,
- grep {
- !Foomatic::DB::member($_, @existing);
- } map {
- m:^(.*)\.xml$:; $1;
- } map {
- m:([^/]+)$:; $1;
- } split(/\n/s,
- `find $libdir/db/source/printer -name "*.xml" -print0 | xargs -0 grep -l $ppddlpath`));
- my $entryfound = 0;
- foreach my $entry (@existing) {
- my $d = $db->get_printer($entry);
- my $result;
- next if $d->{'noxmlentry'};
- $entryfound = 1;
- last if $nomod;
- $db->{'dat'} = $d;
- if (!defined($parameters->{'drivers'})) {
- $parameters->{'drivers'} = [$dat->{'driver'}];
- }
- if (!defined($parameters->{'pdls'})) {
- $parameters->{'pdls'} = [split(',', $dat->{'general_cmd'})];
- } else {
- push(@{$parameters->{'pdls'}}, split(',', $dat->{'general_cmd'}));
- }
- Foomatic::DB::apply_driver_and_pdl_info($db->{'dat'}, $parameters);
- $db->{'dat'}{'general_ieee'} = $dat->{'general_ieee'} if
- defined($dat->{'general_ieee'}) &&
- !defined($db->{'dat'}{'general_ieee'});
- $db->{'dat'}{'general_mfg'} = $dat->{'general_mfg'} if
- defined($dat->{'general_mfg'}) &&
- !defined($db->{'dat'}{'general_mfg'});
- $db->{'dat'}{'general_mdl'} = $dat->{'general_mdl'} if
- defined($dat->{'general_mdl'}) &&
- !defined($db->{'dat'}{'general_mdl'});
- $db->{'dat'}{'general_des'} = $dat->{'general_des'} if
- defined($dat->{'general_des'}) &&
- !defined($db->{'dat'}{'general_des'});
- $db->{'dat'}{'general_cmd'} = $dat->{'general_cmd'} if
- defined($dat->{'general_cmd'}) &&
- !defined($db->{'dat'}{'general_cmd'});
- $db->{'dat'}{'comment'} .= "\n <p>\n\n" . $dat->{'comment'};
- my $xml1 = $db->perltoxml('p');
- my $xml2 = $db->get_printer_xml($entry);
- $xml2 =~ s/(<\/functionality>)/$1\n <driver><\/driver>/s if
- $xml2 !~ /<driver>/;
- $xml2 = transferregexp($xml1, $xml2,
- '<driver>\S*<\/driver>');
- $xml2 =~ s/(<\/driver>)/$1\n <drivers>\n <\/drivers>/s if
- $xml2 !~ /<drivers>/;
- $xml2 = transferregexp($xml1, $xml2,
- '<drivers>.*<\/drivers>');
- $xml2 =~ s/(<\/(mechanism|url)>)/$1\n <lang>\n <\/lang>/s if
- $xml2 !~ /<lang>/;
- $xml2 = transferregexp($xml1, $xml2,
- '<lang>.*<\/lang>');
- $xml2 =~ s/(<\/lang>)/$1\n <autodetect>\n <\/autodetect>/s if
- $xml2 !~ /<autodetect>/;
- $xml2 =~ s/(<autodetect>)/$1\n <general>\n <\/general>/s if
- $xml2 !~ /<autodetect>[\s\n\r]*<general>/s;
- $xml2 = transferregexp($xml1, $xml2,
- '<autodetect>[\s\n\r]*<general>.*<\/general>');
- $xml2 = transferregexp($xml1, $xml2,
- '<\/drivers>[\s\n\r]*<comments>.*<\/comments>[\s\n\r]*<\/printer>');
- $result = $xml2;
- print "Modifying printer entry $db->{'dat'}{'id'}.xml ...\n";
- open FILE, "> " . ($destdir ? $destdir . "/" : ()) .
- $db->{'dat'}{'id'} . ".xml" or
- die "Cannot write file $db->{'dat'}{'id'}.xml!\n";
- print FILE $result;
- close FILE;
- delete($db->{'dat'});
- }
- if (!$entryfound) {
- $db->{'dat'} = $dat;
- $db->{'dat'}{'comment'} =
- " This database entry was automatically generated\n" .
- " from the PPD file for this printer.<p>\n\n" .
- $db->{'dat'}{'comment'};
- $db->{'dat'}{'functionality'} = "A";
- foreach my $product (@{$db->{'dat'}{ppdproduct}}) {
- $db->{'dat'}{'model'} =
- Foomatic::DB::clean_manufacturer_name(Foomatic::DB::clean_model_name($product))
- if scalar(@{$db->{'dat'}{ppdproduct}}) > 1;
- $db->{'dat'}{'model'} =~ s/^$db->{'dat'}{'make'}\s*//i;
- $db->{'dat'}{'id'} =
- Foomatic::DB::generatepid($db->{'dat'}{'make'},
- $db->{'dat'}{'model'});
- if (scalar(@{$db->{'dat'}{ppdproduct}}) > 1) {
- $db->{'dat'}{'general_mfg'} = $db->{'dat'}{'ppdmanufacturer'} if
- $db->{'dat'}{'ppdmanufacturer'} &&
- !$db->{'dat'}{'general_mfg'};
- $db->{'dat'}{'general_mdl'} = $product;
- $db->{'dat'}{'general_ieee'} = "MFG:" .
- $db->{'dat'}{'general_mfg'} .
- ";MDL:" . $db->{'dat'}{'general_mdl'} . ";" .
- ($db->{'dat'}{'general_cmd'} ?
- "CMD:" . $db->{'dat'}{'general_cmd'} . ";" : "");
- }
- $result = $db->perltoxml('p');
- print "Creating new printer entry $db->{'dat'}{'id'}.xml ...\n";
- open FILE, "> " . ($destdir ? $destdir . "/" : ()) .
- $db->{'dat'}{'id'} . ".xml" or
- die "Cannot write file $db->{'dat'}{'id'}.xml!\n";
- print FILE $result;
- close FILE;
- }
- delete($db->{'dat'});
- }
-
- exit 0;
-
- sub transferregexp {
-
- my ($src, $dest, $regexp) = @_;
-
- # This function copies the text fraction matching $regexp out of
- # the first string, cuts the piece of the second matching $regexp
- # out of the second string and replaces it by the piece copied
- # from the first string. This is mainly for transfering XML
- # sections from one XML file to another (strings can be
- # multi-line) without needing to rewrite the unaffected parts of
- # the XML file.
-
- $src =~ m/($regexp)/s;
- my $totransfer = $1;
- $dest =~ s/$regexp/$totransfer/s if $totransfer;
- return $dest;
- }
-
- sub help {
- print <<HELP;
-
- $progname <options> <ppdfile>
- $progname -h
-
- <ppdfile> : PPD file for which a printer XML file should be created
- -d <drivers> : Comma-separated list of drivers with which the printer
- works. First driver is the one for which the PPD file is.
- If not otherwise stated by the "-r" options, this is also
- the recommended driver.
- -r <driver> : Recommended driver. Supply this option to specify another
- driver than the driver from the PPD/the first one from the
- "-d" argument as the recommended driver.
- -p <pdls> : Comma-separated list of known Page Description Languages
- (PDLs) which the printer supports. This will add all
- suitable drivers to the XML entry. Currently supported are:
- Postscript, PCLXL, PCL6, PCL5e, PCL5c, PCL5, and PCL4.
- -l : Add a link to the PPD file to the driver entry in the
- XML file.
- -b <directory> : Base directory for a relative link to the PPD. If the
- base directory is given, the link set via the -l option
- is relative to this directory (and not relative to the
- current directory). With a base directory given the
- <ppdfile> can also be given relative to this directory.
- -f <directory> : Directory where the resulting XML file to write to. The
- name of the file will be the printer ID with the ".xml"
- extension.
- -n : Do not write modified versions of existing XML files,
- only create XML files for printer for which there is no
- XML file yet.
- -h : show help information
-
-
- HELP
- exit 1;
-
- }
-